package br.edu.ufc.deti.servlets;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.exolab.castor.mapping.MappingException;
import org.exolab.castor.xml.MarshalException;
import org.exolab.castor.xml.ValidationException;

import br.edu.ufc.deti.beans.Aplicacao;
import br.edu.ufc.deti.beans.PerfClusters;
import br.edu.ufc.deti.beans.Recurso;
import br.edu.ufc.deti.beans.Requisito;
import br.edu.ufc.deti.broker.mapeamento.ExecucaoMapping;
import br.edu.ufc.deti.broker.mapeamento.bean.PerfClustersDecorator;
import br.edu.ufc.deti.broker.services.ExecucaoProxy;
import br.edu.ufc.deti.util.Utils;

import javax.servlet.annotation.WebServlet;

/**
 * Servlet implementation class ServletRequisito
 */
@WebServlet("/ServletExecucao")
public class ServletExecucao extends HttpServlet {
	
	private final String pathServer = "/home/antonio/workspace_helios/perfclusters";
	private static final long serialVersionUID = 1L;

	protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		PerfClustersDecorator decorator1 = new PerfClustersDecorator(Utils.populaPerfClusters());
		decorator1.setPerfClusters( request2PerfClusters( req ) );
		ExecucaoProxy execucaoProxy = new ExecucaoProxy();
		try{
			String pcXML = ExecucaoMapping.getInstance().marshalPerfClusters(decorator1);
			System.out.println("XML de envio..."+pcXML);
			String pcXMLResult = execucaoProxy.executaAplicacao_Recursos(pcXML);
			System.out.println("XML de resposta..."+pcXMLResult);
			PerfClusters perfClusters = ExecucaoMapping.getInstance().unmarshalPerfClusters(pcXMLResult, decorator1);
			ServletOutputStream os;
			if( perfClusters.getMensagens() == null ){
				res.setContentType("inline/download");
				res.setHeader("Content-Disposition", "attachment;filename=resultado.txt");   
				os = res.getOutputStream();
				File arquivoResultado = new File(pathServer+"/WebContent/resultados/results.txt"); 
				os.write( Utils.read( arquivoResultado ) );   
				os.flush();os.close();
			}else{
				PrintWriter out = res.getWriter();
				out.println(pcXMLResult);		
			}
		} catch (MarshalException e) {
			e.printStackTrace();
		} catch (ValidationException e) {
			e.printStackTrace();
		} catch (MappingException e) {
			e.printStackTrace();
		}
	}

	/**
	 * @param req
	 * @return 
	 * @throws IOException 
	 */
	private PerfClusters request2PerfClusters( HttpServletRequest req ) throws IOException {
		PerfClusters perfClusters = new PerfClusters();

		Aplicacao aplicacao = new Aplicacao();
		aplicacao.setBase(req.getParameter("base"));
		aplicacao.setNome("mpiBLAST");

		FileWriter fileWriterApp = new FileWriter( pathServer+"/scripts-apps/input.in" );
		fileWriterApp.write(req.getParameter("sequencia"));
		fileWriterApp.close();
	
		aplicacao.setSequencia(req.getParameter("sequencia"));
		perfClusters.setAplicacao(aplicacao);


		req.getParameter("dias_tempo_estimado");
		req.getParameter("horas_tempo_estimado");
		req.getParameter("minutos_tempo_estimado");
		req.getParameter("segundos_tempo_estimado");
		
		
		//intensidade utilizacao requisitos
		List<Requisito> requisitos = new ArrayList<Requisito>();
		List<String> nomesRequisistos = new ArrayList<String>();
		nomesRequisistos.add(req.getParameter("processamento"));
		nomesRequisistos.add(req.getParameter("memoria"));
		nomesRequisistos.add(req.getParameter("rede_interna"));
		nomesRequisistos.add(req.getParameter("rede_externa"));

		Requisito recurso;
		for (String string : nomesRequisistos) {
			recurso = new Requisito();
			String nomeRequisito = string.substring(2, string.length());
			recurso.setDscRequisito(nomeRequisito);
			recurso.setValorMinimoRequisito(Float.parseFloat(req.getParameter("val_min_"+nomeRequisito)));
			recurso.setUsoRequisito(Float.parseFloat(string.substring(0, 1)));
			requisitos.add(recurso);
			recurso = null;
		}
		perfClusters.setRequisitos(requisitos);
		
		//recursos
		//List<Recurso> recursos = perfClusters.getRecursos();

		/*for (Iterator iterator = recursos.iterator(); iterator.hasNext();) {
			Recurso recurso = (Recurso) iterator.next();
			if( req.getParameter(recurso.getHostRecurso()) != null ){
				recursosTela.add(recurso);
			}
		}*/

		//Recurso recurso;
		List<String> hostsRecursos = new ArrayList<String>();
		hostsRecursos.add("no1.cenapadne.br");
		hostsRecursos.add("powercost.rcost.unisannio.it");
		hostsRecursos.add("tp-x002.ci.uchicago.edu");
		hostsRecursos.add("tp-x001.ci.uchicago.edu");

		ArrayList<Recurso> recursos = new ArrayList<Recurso>();
		for (String string : hostsRecursos) {
			if(req.getParameter(string)!=null){
				Recurso recursoaaa = new Recurso();
				recursoaaa.setHostRecurso(string);
				recursoaaa.setIpRecurso(req.getParameter(string));
				recursos.add(recursoaaa);
				recursoaaa = null;
			}
		}
		perfClusters.setRecursos(recursos);
		return perfClusters;
	}
}
